package com.eye.catcher.controller;


import com.eye.catcher.param.CommonResponse;
import com.eye.catcher.param.ResponseData;
import com.eye.catcher.param.ResponseUtil;
import com.eye.catcher.constants.RedisConstants;
import com.eye.catcher.constants.SbCode;
import com.eye.catcher.log.param.LogDto;
import com.eye.catcher.log.param.LogPage;
import com.eye.catcher.rabbit.MQDto;
import com.eye.catcher.service.ITLogDaOperationService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.amqp.core.Message;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.util.Date;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author huzhiwei
 * @since 2022-02-10
 */
@Slf4j
@Controller
@RabbitListener(queues = "OperationDirectQueue")
@RequestMapping("/eyeCatcher-log/log-operation")
public class TLogDaOperationController extends TLogBaseController {
    private final static String MODULE_CODE = "/log-abnormal";
    private final static String MODULE_NAME = "操作日志";

    @Autowired
    private ITLogDaOperationService operationService;

    @RabbitHandler
    public void process(Map<String,Object> map, Message message, Channel channel) {
        log.info("接收消息：" + map);
        log.info("接收消息时间：" + new Date());
        try {
//          存储
            LogDto logDto = (LogDto)map.get("messageData");
            operationService.saveOperationLog(logDto);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        }catch (Exception e){
            String key = RedisConstants.RABBIT_INFO_EXPIRE.getKey() + String.valueOf(map.get("messageId"));
            int num = 1;
            if(redisUtils.hasKey(key)){
                num = (int)redisUtils.get(key);//失败过了
                if(num > 5){
                    //失败 大于五次 做处理，存储到日志，手动确认
                    log.error("Rabbit-mq消息五次重复发送解析失败：参数{} ",map.toString());
                    try { //手动确认mq 消息接受
                        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                    return;
                }
                num++;
                redisUtils.set(key,num,RedisConstants.RABBIT_INFO_EXPIRE.getTime());
            }
            try {//失败  mq 重新发送
                redisUtils.set(key,num,RedisConstants.RABBIT_INFO_EXPIRE.getTime());
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }
    }

    @PostMapping("/getPageList")
    @ResponseBody
    public ResponseData getList(@RequestBody LogDto logDto) {
        String methodCode = "/getPageList";
        MQDto mqDto = null;
        try{
            mqDto = new MQDto(methodCode,getLoginUserId(),MODULE_CODE,MODULE_NAME,getClass(), SbCode.OPERATION_QUERY,logDto.toString(),null,null);
//            this.sendInitRabbitMqLog(mqDto);
            commonResponse = CommonResponse.success();
            commonResponse.setData(
                    this.operationService.getPageList(
                            LogPage.builder()
                                    .log(logDto)
                                    .page(this.getPageInfo(logDto))
                                    .build()
                    )
            );
            log.info(methodCode, commonResponse.toString());
        }catch (Exception e){
            e.printStackTrace();
            this.sendAbnormalRabbitMqLog(mqDto.addException(e));
            log.error(methodCode+"/n", e);
            commonResponse = CommonResponse.error();
//        }finally {
//            this.sendFinishRabbitMqLog(mqDto.addResult(commonResponse));
        }
        return new ResponseUtil<>().setData(commonResponse);
    }
}
